home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_2
/
snap
/
snap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-13
|
34KB
|
1,631 lines
/*
* $VER:Snap.c - (10.09.95) 12:15:52 Copyright © 1995 by Mikael Karlsson & Sylvain ROUGIER
*
* Created: 1988
* Modified: 10 Sep 1995 12:15:52
*
* Make>> smake
*
* 04/06/95:
* Try to compile originale Snap 1.61 src
* Bumped to 1.99
* 04/06/95:
* Bumped to 2.00
* try to fix bug occuring when cliping gfx on >6 depth screen
* 10/09/95:
* the SwapColor seem not work under CyberGFX V40.?, this is not true, it seems to be a bug of CyberGFX.
*/
/***********************************************\
* *
* Snap *
* © Mikael Karlsson 1988-1991 *
* *
\***********************************************/
/* Auto: make "CCEXTRA=-wq -qf"
*/
#include <stdio.h>
#include "Snap.h"
#include "proto/Misc.h"
#include "proto/GfxSnap.h"
#ifdef SNAPREXX
#include "minrexx.h"
#include "proto/MinRexx.h"
#endif /* SNAPREXX */
#define ARGVAL( ) ( ( *argv && *++( *argv)) || ( --argc && *++argv))
char Version[ ] = "$VER: 2.00 © 1991 Mikael Karlsson,Absolut Software & Sylvain ROUGIER\n";
BOOL Kick36;
/* signals */
LONGBITS startsignal, insertsignal, cancelsignal;
LONGBITS donesignal, movesignal, clicksignal;
LONGBITS timersignal, initsignal, cwsignal, ticksignal;
ULONG startsignum = -1L;
ULONG insertsignum = -1L;
ULONG cancelsignum = -1L;
ULONG donesignum = -1L;
ULONG movesignum = -1L;
ULONG clicksignum = -1L;
ULONG initsignum = -1L;
ULONG cwsignum = -1L;
ULONG ticksignum = -1L;
ULONG WaitSignal;
/* program */
struct SnapRsrc *SnapRsrc = NULL;
struct Task *MyTask;
/* Snap state machine */
WORD action;
WORD state;
/* clipboard */
struct IOClipReq *ClipReq = NULL;
struct MsgPort *ClipPort = NULL;
/* timer device */
struct MsgPort *TimerPort = NULL;
struct timerequest MyTR;
/* input device */
struct MsgPort *inputDevPort = NULL;
struct Interrupt handlerStuff;
struct IOStdReq *inputRequestBlock = NULL;
struct InputEvent SimEvent;
WORD textqual;
WORD gfxqual;
WORD insertkey;
WORD cwkey;
WORD modinsert;
UBYTE *CharData = NULL;
UBYTE TrueUnderscore;
/* console */
struct MsgPort *ConPort = NULL;
struct IOStdReq *ConIOR = NULL;
struct KeyMap keymap;
/* windows */
#ifdef SNAPGFX
struct MsgPort *Sharedport = NULL;
SHORT Sharedrefs;
IMPORT struct Window *ControlWindow;
struct Window *SaveWin = NULL;
IMPORT struct Gadget SaveGad;
IMPORT struct Gadget NameGad;
IMPORT struct StringInfo TranspSI;
IMPORT struct Image ActiveDiskImage;
IMPORT struct Image InactiveDiskImage;
IMPORT struct Image ActiveClipImage;
IMPORT struct Image InactiveClipImage;
#endif /* SNAPGFX */
IMPORT UBYTE *WindowTitle;
/* libraries */
IMPORT struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct Library *LayersBase = NULL;
struct Library *DiskfontBase = NULL;
struct Library *IconBase = NULL;
#ifdef SNAPGFX
#ifdef REQLIB
struct ReqBase *ReqBase = NULL;
#endif /* REQLIB */
#ifdef ASLLIB
struct Library *AslBase = NULL;
#endif /* ASLLIB */
#endif /* SNAPGFX */
/* graphics */
struct Screen *theScreen;
struct RastPort rp, TempRp, MyRP;
struct BitMap TempBM, MyBM;
UBYTE *TempRaster = NULL;
#ifdef SNAPGFX
#ifdef REQLIB
struct ReqFileRequester *NameFR = NULL;
#endif /* REQLIB */
#ifdef ASLLIB
struct FileRequester *AslNameFR = NULL;
#endif /* ASLLIB */
char SaveName[ DSIZE + FCHARS + 2];
BPTR SnapFile;
#endif /* SNAPGFX */
/* ARexx stuff */
#ifdef SNAPREXX
ULONG rexxsignal;
IMPORT struct rexxCommandList rcl[ ];
//WORD disp( );
#endif /* SNAPREXX */
#ifdef AZTEC_C
int stricmp( char *s1, char *s2)
{
char c1, c2;
while ( *s1 && *s2)
{
if ( ( c1 = *( s1++)) >= 'a' && c1 <= 'z')
{
c1 -= 32;
}
if ( ( c2 = *( s2++)) >= 'a' && c2 <= 'z')
{
c2 -= 32;
}
if ( c1 != c2)
{
return ( c1 - c2);
}
}
return ( *s1 - *s2);
}
int strnicmp( char *s1, char *s2, int n)
{
char c1, c2;
while ( *s1 && *s2 && --n > 0)
{
c1 = *( s1++);
c2 = *( s2++);
if ( c1 >= 'a' && c1 <= 'z')
{
c1 -= 32;
}
if ( c2 >= 'a' && c2 <= 'z')
{
c2 -= 32;
}
if ( c1 != c2)
{
return ( c1 - c2);
}
}
c1 = *s1;
c2 = *s2;
if ( c1 >= 'a' && c1 <= 'z')
{
c1 -= 32;
}
if ( c2 >= 'a' && c2 <= 'z')
{
c2 -= 32;
}
return ( c1 - c2);
}
#endif
LONG dectoint( REGISTER char *str)
{
REGISTER long val = 0;
REGISTER char c;
while ( ( c = *str) >= '0' && c <= '9')
{
val = ( ( ( val << 2) + val) << 1) + c - '0';
str++;
}
return ( val);
}
LONG HexToInt( char *str)
{
REGISTER long val = 0;
REGISTER char c;
if ( !strnicmp( str, "0x", 2))
{
str += 2;
}
while ( c = *str)
{
val <<= 4;
val |= ( c & 15) + ( ( c >= '0' && c <= '9') ? 0 : 9);
str++;
}
return val;
}
WORD insertcount;
VOID InsertAscii( ULONG ascii)
{
if ( insertcount == 1)
{ /* Time for second char */
/* Not necessary to patch here but it guarantees
that all inserted chars end up in the same window. */
SafePatch( );
}
if ( AsciiToInputEvent( ascii, &SimEvent, &keymap))
{
DoIO( ( struct IORequest *)inputRequestBlock);
if ( SnapRsrc->chardelay)
{
MyTR.tr_node.io_Command = TR_ADDREQUEST;
MyTR.tr_time.tv_micro = SnapRsrc->chardelay;
MyTR.tr_time.tv_secs = 0;
DoIO( ( struct IORequest *)&MyTR);
}
}
++insertcount;
}
#ifdef SNAPGFX
VOID GadText( struct Gadget *Gad, char *Str, LONG Len)
{
char temp[ 256];
SHORT i;
SetDrMd( ControlWindow->RPort, JAM2);
SetAPen( ControlWindow->RPort, 0L);
RectFill( ControlWindow->RPort, ( LONG) Gad->LeftEdge, ( LONG) Gad->TopEdge,
( LONG) Gad->LeftEdge + Gad->Width - 1, ( LONG) Gad->TopEdge + Gad->Height - 1);
SetAPen( ControlWindow->RPort, 1L);
SetBPen( ControlWindow->RPort, 0L);
Move( ControlWindow->RPort,
( LONG) Gad->LeftEdge + 1,
( LONG) Gad->TopEdge + ControlWindow->RPort->Font->tf_Baseline + 1);
if ( TextLength( ControlWindow->RPort, Str, Len) > Gad->Width)
{
i = Len;
strncpy( temp, Str, i - 3);
strcat( temp, "...");
while ( TextLength( ControlWindow->RPort, temp, ( LONG) i) > Gad->Width)
{
--i;
temp[ i] = '\0';
temp[ i - 3] = '.';
}
Text( ControlWindow->RPort, temp, ( LONG) i);
}
else
{
Text( ControlWindow->RPort, Str, Len);
}
}
VOID SwapColorMap( struct GfxSnap *GS)
{
struct ViewPort *vp = &GS->window->WScreen->ViewPort;
LONG i = ( GS->viewmode & HAM ? 16 : 1L << GS->depth);
ULONG col;
if ( SysBase->LibNode.lib_Version < 39)
{
while ( i-- && ( col = GetRGB4( vp->ColorMap, i)) != -1L)
{
SetRGB4( vp, i,
( LONG) GS->rgb[ i][ 0] >> 4,
( LONG) GS->rgb[ i][ 1] >> 4,
( LONG) GS->rgb[ i][ 2] >> 4);
GS->rgb[ i][ 0] = RGB4ToRR( col);
GS->rgb[ i][ 1] = RGB4ToGG( col);
GS->rgb[ i][ 2] = RGB4ToBB( col);
}
}
else
{
while ( i--)
{
ULONG RGB[ 3];
GetRGB32( vp->ColorMap, i, 1, RGB);
SetRGB32CM( vp->ColorMap, i, RGB8ToRGB32( GS->rgb[ i][ 0]), RGB8ToRGB32( GS->rgb[ i][ 1]), RGB8ToRGB32( GS->rgb[ i][ 2]));
GS->rgb[ i][ 0] = RGB32ToRGB8( RGB[ 0]);
GS->rgb[ i][ 1] = RGB32ToRGB8( RGB[ 1]);
GS->rgb[ i][ 2] = RGB32ToRGB8( RGB[ 2]);
}
}
}
VOID CheckWindowMsgs( )
{
struct IntuiMessage *Msg;
struct IntuiMessage *QdMsg = NULL;
ULONG im_Class;
USHORT Code;
struct Window *Win;
struct Gadget *Gad;
struct GfxSnap *SwapGS = NULL;
while ( Sharedport &&
( QdMsg || ( Msg = ( struct IntuiMessage *)GetMsg( Sharedport))))
{
if ( QdMsg)
{
Msg = QdMsg;
QdMsg = NULL;
}
im_Class = Msg->Class;
Code = Msg->Code;
Win = Msg->IDCMPWindow;
Gad = ( struct Gadget *)Msg->IAddress;
ReplyMsg( ( struct Message *)Msg);
switch ( im_Class)
{
case CLOSEWINDOW:
{
struct GfxSnap *GS = NULL;
if ( Win == ControlWindow)
{
ControlWindow = NULL;
if ( SaveWin)
{
SetWindowTitles( SaveWin, ( char *)WindowTitle, ( char *)-1);
SaveWin = NULL;
}
}
else
{
GS = ( struct GfxSnap *)Win->UserData;
Snp_FreeBitMap( GS->BitMap, GS->width, GS->height);
GS->BitMap = NULL;
if ( Win == SaveWin || Sharedrefs == 1)
{
if ( ControlWindow)
{
OffGadget( &SaveGad, ControlWindow, NULL);
}
SaveWin = NULL;
}
}
closesharedwindow( Win);
DeleteGfxSnap( GS);
break;
}
case NEWSIZE:
{
AdjustSize( ( struct GfxSnap *)Win->UserData);
break;
}
case MOUSEMOVE:
{
/* Collapse all consecutively queued MOUSEMOVE msgs */
while ( ( QdMsg = ( struct IntuiMessage *)GetMsg( Sharedport))
&& ( QdMsg->Class == MOUSEMOVE))
{
ReplyMsg( ( struct Message *)QdMsg);
}
SyncGS( ( struct GfxSnap *)Win->UserData);
break;
}
case REFRESHWINDOW:
{
BeginRefresh( Win);
SyncGS( ( struct GfxSnap *)Win->UserData);
EndRefresh( Win, 1L);
}
case INACTIVEWINDOW:
{
if ( Win != ControlWindow)
{
struct GfxSnap *GS;
GS = ( struct GfxSnap *)Win->UserData;
if ( SwapGS)
{
SwapColorMap( SwapGS);
SwapGS = NULL;
}
GS->DiskGad.GadgetRender = ( APTR) & InactiveDiskImage;
GS->ClipGad.GadgetRender = ( APTR) & InactiveClipImage;
RefreshGList( &GS->DiskGad, GS->window, NULL, -1);
}
break;
}
case ACTIVEWINDOW:
{
if ( Win != ControlWindow)
{
struct GfxSnap *GS;
GS = ( struct GfxSnap *)Win->UserData;
GS->DiskGad.GadgetRender = ( APTR) & ActiveDiskImage;
GS->ClipGad.GadgetRender = ( APTR) & ActiveClipImage;
RefreshGList( &GS->DiskGad, GS->window, NULL, -1);
}
break;
}
case GADGETUP:
{
switch ( Gad->GadgetID)
{
case VPROP:
case HPROP:
{
SyncGS( ( struct GfxSnap *)Win->UserData);
break;
}
case SAVEGAD:
{
savepic:
if ( SaveWin)
{
WORD success = 0;
struct GfxSnap *GS;
GS = ( struct GfxSnap *)SaveWin->UserData;
if ( SaveName[ 0] == '\0')
{
DisplayBeep( NULL);
ActivateGadget( &NameGad, ControlWindow, NULL);
break;
}
SnapFile = ( BPTR) Open( ( char *)SaveName, MODE_NEWFILE);
if ( SnapFile)
{
struct CBFHandle CBFH;
CBFH.Type = CBFFILE;
CBFH.Handle.File = SnapFile;
success = SaveGS( GS, &CBFH);
Close( SnapFile);
}
if ( success)
{
SetWindowTitles( ControlWindow, "Saved ok", ( char *)-1);
}
else
{
DeleteFile( ( char *)SaveName);
DisplayBeep( NULL);
SetWindowTitles( ControlWindow, "Save failed", ( char *)-1);
}
}
break;
}
case NAMEGAD:
{ /* Should only happen with Req */
#ifdef ASLLIB
if ( ( AslNameFR) && ( Kick36))
{
if ( RequestFile( AslNameFR))
{
strncpy( SaveName, AslNameFR->rf_Dir, sizeof ( SaveName));
AddPart( ( UBYTE *) SaveName,
( UBYTE *) AslNameFR->rf_File,
sizeof ( SaveName));
}
GadText( &NameGad, SaveName, ( LONG) strlen( SaveName));
}
#else
if ( 0)
{
}
#endif /* ASLLIB */
#ifdef REQLIB
else if ( NameFR)
{
NameFR->Title = "Save picture as...";
NameFR->PathName = SaveName;
NameFR->Window = ControlWindow;
( VOID) BruceFileRequester( NameFR);
GadText( &NameGad, SaveName, ( LONG) strlen( SaveName));
}
#endif /* REQLIB */
break;
}
case DISKGAD:
{
struct GfxSnap *GS;
if ( !ControlWindow && !OpenCW( ))
{
DisplayBeep( NULL);
break;
}
if ( Win == SaveWin)
{
goto savepic;
}
if ( SaveWin)
{
SetWindowTitles( SaveWin, ( char *)WindowTitle, ( char *)-1);
GS = ( struct GfxSnap *)SaveWin->UserData;
RefreshGList( &GS->DiskGad, GS->window, NULL, 1L);
}
else
{
GadText( &SaveGad, "Save", 4L);
OnGadget( &SaveGad, ControlWindow, NULL);
}
SaveWin = Win;
SetWindowTitles( SaveWin, "Selected", ( char *)-1);
GS = ( struct GfxSnap *)SaveWin->UserData;
RefreshGList( &GS->DiskGad, GS->window, NULL, 1L);
break;
}
case CLIPGAD:
{
struct CBFHandle CBFH;
struct GfxSnap *GS = ( struct GfxSnap *)Win->UserData;
CBFH.Type = CBFCLIP;
CBFH.Handle.ClipReq = ClipReq;
if ( !SaveGS( GS, &CBFH))
{
DisplayBeep( NULL);
}
break;
}
default:
{
break;
}
}
break;
}
case MOUSEBUTTONS:
{
if ( Win != ControlWindow)
{
if ( Code == SELECTDOWN && !SwapGS)
{
SwapGS = ( struct GfxSnap *)Win->UserData;
SwapColorMap( SwapGS);
}
else if ( Code == SELECTUP && SwapGS)
{
SwapColorMap( SwapGS);
SwapGS = NULL;
}
}
break;
}
default:
{
break;
}
}
}
if ( QdMsg)
{
ReplyMsg( ( struct Message *)QdMsg);
}
}
#endif /* SNAPGFX */
#define SnapWriteStr( str) fputs( str, stdout)
#define SnapWriteChar( char) fputc( char, stdout)
struct QualPair
{
char *str;
WORD val;
};
struct QualPair Qualifiers[ ] =
{
{"LSHIFT", IEQUALIFIER_LSHIFT},
{"RSHIFT", IEQUALIFIER_RSHIFT},
{"CONTROL", IEQUALIFIER_CONTROL},
{"LALT", IEQUALIFIER_LALT},
{"RALT", IEQUALIFIER_RALT},
{"LCOMMAND", IEQUALIFIER_LCOMMAND},
{"RCOMMAND", IEQUALIFIER_RCOMMAND},
{"MIDBUTTON", IEQUALIFIER_MIDBUTTON}
};
WORD ParseQual( char *quals)
{
char *temp;
WORD i;
char oldc;
WORD qual = 0;
if ( ( '0' >= *quals) && ( *quals <= '9'))
{
return ( WORD)HexToInt( quals);
}
while ( *quals)
{
temp = quals;
while ( ( oldc = *quals) && oldc != '+')
{
quals++;
}
*quals = 0;
for ( i = 0; i < ( sizeof ( Qualifiers) / sizeof ( Qualifiers[ 0])); i++)
{
if ( !stricmp( temp, Qualifiers[ i].str))
{
qual |= Qualifiers[ i].val;
break;
}
}
if ( *quals = oldc)
{
quals++;
}
}
return qual;
}
WORD SetAltFont( char *str)
{
struct TextAttr ta;
struct TextFont *NewFont;
char temp[ 33];
WORD pos = 0;
if ( strlen( str) <= 32)
{
strcpy( temp, str);
ta.ta_Name = ( UBYTE *) temp;
while ( temp[ pos] != '\0' && temp[ pos] != '/')
{
++pos;
}
if ( temp[ pos] == '\0')
{ /* No size */
ta.ta_YSize = 8;
}
else
{
temp[ pos] = '\0';
ta.ta_YSize = dectoint( &temp[ pos + 1]);
}
if ( pos > 5)
{
if ( stricmp( &temp[ pos - 5], ".font"))
{
strcpy( &temp[ pos], ".font");
}
}
else
{
strcpy( &temp[ pos], ".font");
}
ta.ta_Style = 0;
ta.ta_Flags = 0;
NewFont = SmartOpenFont( &ta);
if ( NewFont)
{
if ( SnapRsrc->AlternateFont)
{
CacheSync( SnapRsrc->AlternateFont);
CloseFont( SnapRsrc->AlternateFont);
}
SnapRsrc->AlternateFont = NewFont;
}
}
return ( WORD)( NewFont ? 1 : 0);
}
struct SnapRsrc DefaultRsrc =
{
{NULL, NULL, NT_RESOURCE, 0, SNAPRSRC}, /* Node */
NULL, /* Task */
52, /* Priority */
IEQUALIFIER_RCOMMAND, /* Graphics qualifier */
IEQUALIFIER_LCOMMAND, /* Text qualifier */
0x17, /* Insert key */
0x11, /* Control Window key */
{'>', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* Prepend */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* Append */
TRUEUNDERSCORE, /* Flags */
0, /* Char delay */
0, /* Line delay */
0x7777, /* Crawl pattern */
UNIT_FRAME, /* Starting unit */
1, /* Frame mask */
'?', /* Bad char */
10, /* Cache size */
1, /* Extra line spacing */
{NULL, NULL, NULL}, /* MinList, Cached windows */
NULL /* Alternate font */
};
#ifdef LATTICE
VOID main( int argc, char **argv)
#else
WORD main( int argc, char **argv)
#endif
{
WORD create = 0, usage = 0;
#ifdef AZTEC_C
Enable_Abort = 0;
#endif /* AZTEC_C */
Kick36 = ( SysBase->LibNode.lib_Version >= 36 ? 1 : 0);
if ( !( SnapRsrc = ( struct SnapRsrc *)OpenResource( SNAPRSRC)))
{
create = 1;
SnapRsrc = Create( SnapRsrc);
CopyMem( ( char *)&DefaultRsrc, ( char *)SnapRsrc, sizeof ( struct SnapRsrc));
SnapRsrc->Task = FindTask( NULL);
NewList( ( struct List *)&SnapRsrc->CachedWindows);
AddResource( ( struct MiscResource *)SnapRsrc);
}
/* Open libraries since we might need them when parsing arguments */
if ( !OpenLibs( ))
{
goto exitpoint;
}
if ( !argc)
{ /* WB Startup */
if ( !create)
{ /* Second time from WB -- Remove Snap */
Signal( SnapRsrc->Task, SIGBREAKF_CTRL_C);
goto exitpoint;
}
else if ( IconBase)
{ /* Is it possible to be started from Workbench
without icon.library being available. */
BPTR olddir;
struct WBStartup *wbstartup;
struct DiskObject *diskobject;
char *val;
wbstartup = ( struct WBStartup *)argv;
olddir = CurrentDir( wbstartup->sm_ArgList[ 0].wa_Lock);
diskobject = GetDiskObject( wbstartup->sm_ArgList[ 0].wa_Name);
if ( !diskobject)
{
goto skipargs;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "PRIORITY"))
{
WORD pri = dectoint( val);
if ( pri > 50 && pri < 128)
{
SnapRsrc->Priority = pri;
}
}
if ( val = FindToolType( diskobject->do_ToolTypes, "TEXTQUAL"))
{
if ( !( SnapRsrc->textqual = ParseQual( val)))
{
SnapRsrc->textqual = IEQUALIFIER_LCOMMAND;
}
}
if ( val = FindToolType( diskobject->do_ToolTypes, "GFXQUAL"))
{
if ( !( SnapRsrc->gfxqual = ParseQual( val)))
{
SnapRsrc->gfxqual = IEQUALIFIER_RCOMMAND;
}
}
if ( val = FindToolType( diskobject->do_ToolTypes, "INSERTKEY"))
{
SnapRsrc->insertkey = HexToInt( val);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "CWKEY"))
{
SnapRsrc->cwkey = HexToInt( val);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "APPEND"))
{
strncpy( &SnapRsrc->Append[ 0], val, 16);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "PREPEND"))
{
strncpy( &SnapRsrc->Prepend[ 0], val, 16);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "CHARDELAY"))
{
SnapRsrc->chardelay = dectoint( val);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "LINEDELAY"))
{
SnapRsrc->linedelay = dectoint( val) * 1000;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "CRAWLPTRN"))
{
SnapRsrc->CrawlPtrn = HexToInt( val);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "XEROX"))
{
SnapRsrc->flags |= XEROX;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "NOXEROX"))
{
SnapRsrc->flags &= ~XEROX;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "EARLYPATCH"))
{
SnapRsrc->flags |= EARLYPATCH;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "NOEARLYPATCH"))
{
SnapRsrc->flags &= ~EARLYPATCH;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "STARTUNIT"))
{
if ( *val == '1')
{
SnapRsrc->StartUnit = UNIT_CHAR;
}
else
{
SnapRsrc->StartUnit = UNIT_FRAME;
}
}
if ( val = FindToolType( diskobject->do_ToolTypes, "TRUEUNDERSCORE"))
{
SnapRsrc->flags |= TRUEUNDERSCORE;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "FAKEUNDERSCORE"))
{
SnapRsrc->flags &= ~TRUEUNDERSCORE;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "JOINLONG"))
{
SnapRsrc->flags |= JOINLONG;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "NOJOINLONG"))
{
SnapRsrc->flags &= ~JOINLONG;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "SIMPLEREFRESH"))
{
SnapRsrc->flags |= SIMPLEREFRESH;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "SMARTREFRESH"))
{
SnapRsrc->flags &= ~SIMPLEREFRESH;
}
if ( val = FindToolType( diskobject->do_ToolTypes, "PLANEMASK"))
{
SnapRsrc->FrameMask = HexToInt( val);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "CACHESIZE"))
{
SnapRsrc->CacheSize = dectoint( val);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "LEADING"))
{
SnapRsrc->Leading = dectoint( val);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "BADCHAR"))
{
SnapRsrc->BadChar = ( *val ? *val : 0);
}
if ( val = FindToolType( diskobject->do_ToolTypes, "ALTFONT"))
{
SetAltFont( val);
}
FreeDiskObject( diskobject);
goto skipargs;
}
}
if ( create)
{
SnapWriteStr( "Snap");
SnapWriteStr( &Version[ 5]);
}
for ( argc--, argv++; argc > 0; argc--, argv++)
{
if ( **argv == '-')
{ /* Argument coming up */
switch ( *++( *argv))
{
case 'p':
priority:{
/* Priority */
if ( ARGVAL( ))
{
WORD pri = dectoint( *argv);
if ( pri > 50 && pri < 128)
{
SnapRsrc->Priority = pri;
}
}
else
{
usage = 1;
}
break;
}
case 't':
textqual:{
if ( ARGVAL( ))
{
if ( !( SnapRsrc->textqual = ParseQual( *argv)))
{
SnapRsrc->textqual = IEQUALIFIER_LCOMMAND;
}
}
else
{
usage = 1;
}
break;
}
#ifdef SNAPGFX
case 'g':
gfxqual:{
if ( ARGVAL( ))
{
if ( !( SnapRsrc->gfxqual = ParseQual( *argv)))
{
SnapRsrc->gfxqual = IEQUALIFIER_RCOMMAND;
}
}
else
{
usage = 1;
}
break;
}
#endif /* SNAPGFX */
case 'i':
insertkey:{
if ( ARGVAL( ))
{
SnapRsrc->insertkey = HexToInt( *argv);
}
else
{
usage = 1;
}
break;
}
#ifdef SNAPGFX
case 'w':
cwkey:{
if ( ARGVAL( ))
{
SnapRsrc->cwkey = HexToInt( *argv);
}
else
{
usage = 1;
}
break;
}
#endif /* SNAPGFX */
case 'c':
chardelay:{
if ( ARGVAL( ))
{
SnapRsrc->chardelay = dectoint( *argv) * 1000;
}
else
{
usage = 1;
}
break;
}
case 'l':
linedelay:{
if ( ARGVAL( ))
{
SnapRsrc->linedelay = dectoint( *argv) * 1000;
}
else
{
usage = 1;
}
break;
}
case 'a':
crawlptrn:{
if ( ARGVAL( ))
{
SnapRsrc->CrawlPtrn = HexToInt( *argv);
}
else
{
usage = 1;
}
break;
}
case 'X':
noxerox:{
SnapRsrc->flags &= ~XEROX;
break;
}
case 'x':
xerox:{
SnapRsrc->flags |= XEROX;
break;
}
case 'E':
noearlypatch:{
SnapRsrc->flags &= ~EARLYPATCH;
break;
}
case 'e':
earlypatch:{
SnapRsrc->flags |= EARLYPATCH;
break;
}
case 'R':
fakeunderscore:{
SnapRsrc->flags &= ~TRUEUNDERSCORE;
break;
}
case 'r':
realunderscore:{
SnapRsrc->flags |= TRUEUNDERSCORE;
break;
}
case 'J':
nojoinlong:{
SnapRsrc->flags &= ~JOINLONG;
break;
}
case 'j':
joinlong:{
SnapRsrc->flags |= JOINLONG;
break;
}
case 'A':
append:{
char *dest = &SnapRsrc->Append[ 0];
if ( ( *argv && *++( *argv)) || ( --argc && ++argv))
{ /* "" is ok */
char *src = *argv;
WORD i = 16;
while ( *src && i--)
{
*dest++ = *src++;
}
*dest = '\0';
}
else
{
usage = 1;
}
break;
}
case 'P':
prepend:{
char *dest = &SnapRsrc->Prepend[ 0];
if ( ( *argv && *++( *argv)) || ( --argc && ++argv))
{ /* "" is ok */
char *src = *argv;
WORD i = 16;
while ( *src && i--)
{
*dest++ = *src++;
}
*dest = '\0';
}
else
{
usage = 1;
}
break;
}
case 'u':
startunit:{
if ( ARGVAL( ))
{
if ( **argv == '1')
{
SnapRsrc->StartUnit = UNIT_CHAR;
}
else
{
SnapRsrc->StartUnit = UNIT_FRAME;
}
}
else
{
usage = 1;
}
break;
}
case 'b':
planemask:{
if ( ARGVAL( ))
{
SnapRsrc->FrameMask = HexToInt( *argv);
}
else
{
usage = 1;
}
break;
}
#ifdef SNAPGFX
case 's':
smartrefresh:{
SnapRsrc->flags &= ~SIMPLEREFRESH;
break;
}
case 'S':
simplerefresh:{
SnapRsrc->flags |= SIMPLEREFRESH;
break;
}
#endif /* SNAPGFX */
case 'C':
cachesize:{
if ( ARGVAL( ))
{
SnapRsrc->CacheSize = dectoint( *argv);
}
else
{
usage = 1;
}
break;
}
case 'L':
leading:{
if ( ARGVAL( ))
{
SnapRsrc->Leading = dectoint( *argv);
}
else
{
usage = 1;
}
break;
}
case 'B':
badchar:{
if ( ARGVAL( ))
{
SnapRsrc->BadChar = dectoint( *argv);
}
else
{
usage = 1;
}
break;
}
case 'F':
altfont:{
if ( ARGVAL( ))
{
SetAltFont( *argv);
}
else
{
usage = 1;
}
break;
}
case 'Q':
case 'q':
quit:{
if ( create)
{
goto close;
}
else
{
Signal( SnapRsrc->Task, SIGBREAKF_CTRL_C);
goto exitpoint;
}
}
case '?':
{
usage = 1;
break;
}
default:
{
SnapWriteStr( "Bad option: -");
SnapWriteChar( ( int)**argv);
SnapWriteStr( ".\n");
usage = 1;
break;
}
}
}
else
{
#ifdef SNAPGFX
char *keyword = *argv;
*argv = NULL;
if ( !stricmp( keyword, "PRIORITY"))
{
goto priority; /* Terrible, ain't it? */
}
else if ( !stricmp( keyword, "TEXTQUAL"))
{
goto textqual;
}
else if ( !stricmp( keyword, "GFXQUAL"))
{
goto gfxqual;
}
else if ( !stricmp( keyword, "INSERTKEY"))
{
goto insertkey;
}
else if ( !stricmp( keyword, "CWKEY"))
{
goto cwkey;
}
else if ( !stricmp( keyword, "PREPEND"))
{
goto prepend;
}
else if ( !stricmp( keyword, "APPEND"))
{
goto append;
}
else if ( !stricmp( keyword, "CHARDELAY"))
{
goto chardelay;
}
else if ( !stricmp( keyword, "LINEDELAY"))
{
goto linedelay;
}
else if ( !stricmp( keyword, "CRAWLPTRN"))
{
goto crawlptrn;
}
else if ( !stricmp( keyword, "XEROX"))
{
goto xerox;
}
else if ( !stricmp( keyword, "NOXEROX"))
{
goto noxerox;
}
else if ( !stricmp( keyword, "EARLYPATCH"))
{
goto earlypatch;
}
else if ( !stricmp( keyword, "NOEARLYPATCH"))
{
goto noearlypatch;
}
else if ( !stricmp( keyword, "TRUEUNDERSCORE"))
{
goto realunderscore;
}
else if ( !stricmp( keyword, "FAKEUNDERSCORE"))
{
goto fakeunderscore;
}
else if ( !stricmp( keyword, "JOINLONG"))
{
goto joinlong;
}
else if ( !stricmp( keyword, "NOJOINLONG"))
{
goto nojoinlong;
}
else if ( !stricmp( keyword, "SIMPLEREFRESH"))
{
goto simplerefresh;
}
else if ( !stricmp( keyword, "SMARTREFRESH"))
{
goto smartrefresh;
}
else if ( !stricmp( keyword, "STARTUNIT"))
{
goto startunit;
}
else if ( !stricmp( keyword, "PLANEMASK"))
{
goto planemask;
}
else if ( !stricmp( keyword, "CACHESIZE"))
{
goto cachesize;
}
else if ( !stricmp( keyword, "LEADING"))
{
goto leading;
}
else if ( !stricmp( keyword, "BADCHAR"))
{
goto badchar;
}
else if ( !stricmp( keyword, "ALTFONT"))
{
goto altfont;
}
else if ( !stricmp( keyword, "QUIT"))
{
goto quit;
}
else if ( stricmp( keyword, "?"))
{
SnapWriteStr( "Bad switch/keyword: ");
SnapWriteStr( keyword);
SnapWriteStr( ".\n");
}
#endif /* SNAPGFX */
usage = 1;
}
}
if ( usage)
{
SnapWriteStr( "Usage:\n");
#ifdef SNAPGFX
SnapWriteStr( " snap -pNN -tQQ -gQQ -iXX -wXX -Pstr -Astr -cNN -lNN\n");
SnapWriteStr( " -aXXXX -x -X -e -E -uN -r -R -j -J -s -S -bXX -CNN\n");
SnapWriteStr( " -LNN -BNN -Ffont -Q\n");
SnapWriteStr( " or\n");
SnapWriteStr( " snap PRIORITY/K TEXTQUAL/K GFXQUAL/K INSERTKEY/K CWKEY/K\n");
SnapWriteStr( " PREPEND/K APPEND/K CHARDELAY/K LINEDELAY/K CRAWLPTRN/K\n");
SnapWriteStr( " XEROX/S NOXEROX/S EARLYPATCH/S NOEARLYPATCH/S STARTUNIT/K\n");
SnapWriteStr( " TRUEUNDERSCORE/S FAKEUNDERSCORE/S JOINLONG/S NOJOINLONG/S\n");
SnapWriteStr( " SIMPLEREFRESH/S SMARTREFRESH/S PLANEMASK/K CACHESIZE/K\n");
SnapWriteStr( " LEADING/K BADCHAR/K ALTFONT/K QUIT/S\n");
#else
SnapWriteStr( " snap -pNN -tQQ -iXX -Pstr -Astr -cNN -lNN\n");
SnapWriteStr( " -aXXXX -x -X -e -E -uN -r -R -j -J -bXX -CNN\n");
SnapWriteStr( " -LNN -BNN -Ffont -Q\n");
#endif /* SNAPGFX */
SnapWriteStr( "\n");
SnapWriteStr( "S-Mail: Mikael Karlsson | E-Mail: micke@slaka.sirius.se\n");
SnapWriteStr( " Lövsättersvägen 10 | micke@slaka.UUCP\n");
SnapWriteStr( " S-585 98 LINKÖPING | {mxvax|seismo}!sunic!liuida!slaka!micke\n");
SnapWriteStr( " Sweden | Phone: +46 ( 0)13 50479\n");
goto exitpoint;
}
skipargs:
freopen( "NIL:", "w", stdout);
if ( !create)
{
/* Tell him there are new settings available */
Signal( SnapRsrc->Task, SIGBREAKF_CTRL_F);
goto exitpoint;
}
if ( !OpenStuff( ))
{
goto close;
}
textqual = SnapRsrc->textqual;
gfxqual = SnapRsrc->gfxqual;
insertkey = SnapRsrc->insertkey;
cwkey = SnapRsrc->cwkey;
TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
#ifdef SNAPGFX
SaveName[ 0] = '\0';
#endif
#ifdef SNAPREXX
rexxsignal = upRexxPort( "SNAP", rcl, NULL, &disp);
#endif /* SNAPREXX */
/* This is what we're waiting for */
WaitSignal = startsignal | insertsignal | initsignal | cancelsignal |
#ifdef SNAPREXX
rexxsignal |
#endif /* SNAPREXX */
cwsignal | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F;
FOREVER
{
REGISTER LONGBITS sig;
sig = Wait( WaitSignal | timersignal
#ifdef SNAPGFX
| ( Sharedport ? ( 1L << Sharedport->mp_SigBit) : 0L)
#endif /* SNAPGFX */
);
#ifdef SNAPGFX
CheckWindowMsgs( );
#endif /* SNAPGFX */
#ifdef SNAPREXX
if ( sig & rexxsignal)
{
dispRexxPort( );
}
#endif /* SNAPREXX */
if ( sig & SIGBREAKF_CTRL_C)
{
/* This is my cue. Exit if there are no open windows depending on us */
#ifdef SNAPGFX
if ( Sharedrefs)
{
DisplayBeep( NULL);
}
else
#endif /* SNAPGFX */
{
goto close;
}
}
if ( sig & SIGBREAKF_CTRL_F)
{
/* Hey, seems like there are new settings available. */
textqual = SnapRsrc->textqual;
gfxqual = SnapRsrc->gfxqual;
insertkey = SnapRsrc->insertkey;
cwkey = SnapRsrc->cwkey;
TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
}
if ( sig & initsignal)
{
if ( SnapRsrc->flags & ( XEROX | EARLYPATCH))
{
SafePatch( ); /* Patch dangerous functions */
}
}
if ( sig & cancelsignal)
{
SafeRestore( );
}
if ( sig & startsignal)
{ /* The handler wants a word in. */
SafePatch( );
#ifdef SNAPGFX
if ( action == snapgfx)
{ /* Check user action */
HandleGfx( ); /* Get the picture :-) */
}
else
#endif /* SNAPGFX */
if ( action == snaptext && HandleChars( ))
{ /* Snap some chars */
if ( SnapRsrc->flags & XEROX)
{
sig |= insertsignal;
}
}
else
{
/* Previous snap wasn't finished when this one started
or this snap failed. */
SetSignal( 0L, movesignal | cancelsignal |
donesignal | clicksignal | ticksignal);
DisplayBeep( NULL);
action = noaction;
}
if ( !( sig & insertsignal))
{
SafeRestore( ); /* Layers unlocked - all safe */
}
}
if ( sig & insertsignal)
{
LONG i;
struct Snap *Snap;
ULONG ascii;
action = insert;
if ( Snap = FetchClip( ))
{ /* Get clipboard data */
/* get the current keymap */
ConIOR->io_Command = CD_ASKDEFAULTKEYMAP;
ConIOR->io_Length = sizeof ( struct KeyMap);
ConIOR->io_Data = ( APTR) & keymap;
ConIOR->io_Flags = 1; /* no IOQuick */
DoIO( ( struct IORequest *)ConIOR);
/* Set up an input request */
inputRequestBlock->io_Command = IND_WRITEEVENT;
inputRequestBlock->io_Flags = 0L;
inputRequestBlock->io_Length = ( long)sizeof ( struct InputEvent);
inputRequestBlock->io_Data = ( APTR) & SimEvent;
/* Translate chars in SnapSpace and insert them
into the input stream. */
insertcount = 0;
ascii = 13; /* Simulate start of new line */
for ( i = 0; Snap->Chars[ i] && ( action == insert); ++i)
{
if ( ascii == 13 && modinsert)
{
int cnt = 0;
while ( ascii = SnapRsrc->Prepend[ cnt++])
{
InsertAscii( ascii);
}
}
ascii = Snap->Chars[ i];
if ( ascii == 10)
{
if ( modinsert)
{
int cnt = 0;
while ( ascii = SnapRsrc->Append[ cnt++])
{
InsertAscii( ascii);
}
}
ascii = 13; /* WYSIWYG? Hah! */
}
InsertAscii( ascii);
if ( ascii == 13 && SnapRsrc->linedelay)
{
MyTR.tr_node.io_Command = TR_ADDREQUEST;
MyTR.tr_time.tv_micro = SnapRsrc->linedelay;
MyTR.tr_time.tv_secs = 0;
DoIO( ( struct IORequest *)&MyTR);
}
}
if ( modinsert)
{
int cnt = 0;
while ( ascii = SnapRsrc->Append[ cnt++])
{
InsertAscii( ascii);
}
}
SafeRestore( ); /* "Depatch" */
/* Free memory given to us by FetchClip( ) */
FreeMem( Snap, Snap->Size);
}
action = noaction;
modinsert = 0;
}
#ifdef SNAPGFX
if ( sig & cwsignal)
{
if ( !ControlWindow && !OpenCW( ))
{
DisplayBeep( NULL);
}
}
#endif /* SNAPGFX */
}
close:
#ifdef SNAPREXX
dnRexxPort( );
#endif /* SNAPREXX */
CloseStuff( ); /* Guess what */
exitpoint:
CloseLibs( );
#ifdef AZTEC_C
return 0;
#endif
}